home *** CD-ROM | disk | FTP | other *** search
- //Note: tristrip backface-culling is disabled for clipping events because of an unidentified bug
-
- #include "sysinc.h"
- #include "vertexarray.h"
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
-
-
- /*
- ** glDrawElements pipeline by Christian 'Surgeon' Michael
- ** Thanks to Olivier Fabre for bug-hunting
- **
- ** major revision 05-07 april 2002:
- ** optimized path for GL_EXT_compiled_vertex_array
- **
- */
-
- extern void TMA_Start(LockTimeHandle *handle);
- extern GLboolean TMA_Check(LockTimeHandle *handle);
- extern void fog_Set(GLcontext context);
-
- void GLLockArrays(GLcontext context, GLuint first, GLsizei count);
- void GLUnLockArrays(GLcontext context);
-
- extern void AE_ClipPoly(GLcontext context, PolyBuffer *out, int clipstart, ULONG or_codes);
-
- extern void m_CombineMatrices(GLcontext context);
-
- extern GLboolean DecideFrontface(GLcontext context, const MGLVertex *a, const MGLVertex *b, const MGLVertex *c, const int sign);
-
- extern Convfn Convert;
-
- GLboolean Clip_Volume_Bypass = GL_FALSE; //for compiled arrays
-
- //NYI:
-
- void E_DrawPoints (GLcontext context, const int count, const UWORD *idx);
- void E_DrawLines (GLcontext context, const int count, const UWORD *idx);
- void E_DrawLineStrip (GLcontext context, const int count, const UWORD *idx);
- void E_DrawLineLoop (GLcontext context, const int count, const UWORD *idx);
-
- void E_DrawQuads (GLcontext context, const int count, const UWORD *idx);
- void E_DrawQuadStrip (GLcontext context, const int count, const UWORD *idx);
-
- //implemented:
-
-
- void E_DrawTriFan (GLcontext context, const int count, UWORD *idx);
-
- void E_DrawPolygon (GLcontext context, const int count, UWORD *idx);
-
- void E_DrawTriStrip (GLcontext context, const int count, const UWORD *idx);
-
- void E_DrawTriangles (GLcontext context, const int count, const UWORD *idx);
-
- void E_DrawFlatFan (GLcontext context, const int count, const UWORD *idx);
-
- static PolyBuffer clip[MGL_MAXVERTS>>2];
- static PolyBuffer polys[MGL_MAXVERTS>>2];
-
-
- INLINE GLboolean E_CheckTri(GLcontext context, const MGLVertex *a, const MGLVertex *b, const MGLVertex *c, const int sign)
- {
- float area;
- float x1,y1;
- float x2,y2;
-
- x1 = b->v.x - a->v.x;
- y1 = b->v.y - a->v.y;
- x2 = c->v.x - a->v.x;
- y2 = c->v.y - a->v.y;
-
- area = y2*x1 - x2*y1;
-
- if(sign > 0)
- area = -area;
-
- if(area < context->MinTriArea)
- return GL_FALSE;
- else
- return GL_TRUE;
- }
-
-
- #define OF_11 0
- #define OF_12 4
- #define OF_13 8
- #define OF_14 12
-
- #define OF_21 1
- #define OF_22 5
- #define OF_23 9
- #define OF_24 13
-
- #define OF_31 2
- #define OF_32 6
- #define OF_33 10
- #define OF_34 14
-
- #define OF_41 3
- #define OF_42 7
- #define OF_43 11
- #define OF_44 15
-
-
- void TransformIndex(GLcontext context, const int size, const UWORD *idx)
- {
- int i;
-
- #define a(x) (context->CombinedMatrix.v[OF_##x])
-
- if(context->ArrayPointer.FixpointTrans == GL_TRUE)
- {
- static int m[16];
- int tx,ty,tz,tw;
- int x,y,z;
- int cw;
- int *vp;
- ULONG local_outcode;
- UBYTE *vpointer;
- MGLVertex *v;
- int stride;
- const float fix2float = 1.f/32768.f;
-
- #define CLIP_EPS ((int)((1e-7)*32768.f))
-
- #define b(x) (m[OF_##x])
-
- if(context->CombinedValid == GL_FALSE)
- {
- const float float2fix = 32768.f;
-
- m_CombineMatrices(context);
-
- b(11)=(int)(a(11)*float2fix);
- b(12)=(int)(a(12)*float2fix);
- b(13)=(int)(a(13)*float2fix);
- b(14)=(int)(a(14)*float2fix);
- b(21)=(int)(a(21)*float2fix);
- b(22)=(int)(a(22)*float2fix);
- b(23)=(int)(a(23)*float2fix);
- b(24)=(int)(a(24)*float2fix);
- b(31)=(int)(a(31)*float2fix);
- b(32)=(int)(a(32)*float2fix);
- b(33)=(int)(a(33)*float2fix);
- b(34)=(int)(a(34)*float2fix);
- b(41)=(int)(a(41)*float2fix);
- b(42)=(int)(a(42)*float2fix);
- b(43)=(int)(a(43)*float2fix);
- b(44)=(int)(a(44)*float2fix);
- }
-
- stride = context->ArrayPointer.vertexstride;
-
- i = size-1;
- do
- {
- v = &(context->VertexBuffer[idx[i]]);
- vpointer = (context->ArrayPointer.verts + idx[i]*stride);
-
- vp = (int *)vpointer;
-
- x = vp[0];
- y = vp[1];
- z = vp[2];
-
- //pipelined transformations
-
- tx = x*b(11);
- ty = x*b(21);
- tz = x*b(31);
- tw = x*b(41);
-
- tx += y*b(12);
- ty += y*b(22);
- tz += y*b(32);
- tw += y*b(42);
-
- tx += z*b(13);
- ty += z*b(23);
- tz += z*b(33);
- tw += z*b(43);
-
- tx += b(14);
- ty += b(24);
- tz += b(34);
- tw += b(44);
-
- local_outcode = 0;
-
- if (tw < CLIP_EPS )
- {
- local_outcode |= MGL_CLIP_NEGW;
- }
- if (-tw > tx)
- {
- local_outcode |= MGL_CLIP_LEFT;
- }
- else if (tx > tw)
- {
- local_outcode |= MGL_CLIP_RIGHT;
- }
-
- if (-tw > ty)
- {
- local_outcode |= MGL_CLIP_BOTTOM;
- }
- else if (ty > tw)
- {
- local_outcode |= MGL_CLIP_TOP;
- }
-
- if (-tw > tz)
- {
- local_outcode |= MGL_CLIP_BACK;
- }
- else if (tz > tw)
- {
- local_outcode |= MGL_CLIP_FRONT;
- }
-
- v->bx = (float)tx*fix2float;
- v->by = (float)ty*fix2float;
- v->bz = (float)tz*fix2float;
- v->bw = (float)tw*fix2float;
-
- v->outcode = local_outcode;
-
- } while (i--);
-
- #undef b
- #undef CLIP_EPS
- }
- else
- {
- float a11,a12,a13,a14;
- float a21,a22,a23,a24;
- float a31,a32,a33,a34;
- float a41,a42,a43,a44;
- float *vp;
- float cw;
- float x,y,z;
- ULONG local_outcode;
- UBYTE *vpointer;
- MGLVertex *v;
- int stride;
-
- #define CLIP_EPS (1e-7)
-
- if(context->CombinedValid == GL_FALSE)
- m_CombineMatrices(context);
-
- a11=a(11); a12=a(12); a13=a(13); a14=a(14);
- a21=a(21); a22=a(22); a23=a(23); a24=a(24);
- a31=a(31); a32=a(32); a33=a(33); a34=a(34);
- a41=a(41); a42=a(42); a43=a(43); a44=a(44);
-
- stride = context->ArrayPointer.vertexstride;
-
- i = size-1;
-
- do
- {
- v = &(context->VertexBuffer[idx[i]]);
- vpointer = (context->ArrayPointer.verts + idx[i]*stride);
- vp = (float *)vpointer;
-
- x = vp[0];
- y = vp[1];
- z = vp[2];
-
- v->bx = a11*x + a12*y + a13*z + a14;
- v->by = a21*x + a22*y + a23*z + a24;
- v->bz = a31*x + a32*y + a33*z + a34;
- v->bw = a41*x + a42*y + a43*z + a44;
-
- cw = v->bw;
- local_outcode = 0;
-
- if (cw < CLIP_EPS )
- local_outcode |= MGL_CLIP_NEGW;
-
- if (-cw > v->bx)
- {
- local_outcode |= MGL_CLIP_LEFT;
- }
- else if (v->bx > cw)
- {
- local_outcode |= MGL_CLIP_RIGHT;
- }
-
- if (-cw > v->by)
- {
- local_outcode |= MGL_CLIP_BOTTOM;
- }
- else if (v->by > cw)
- {
- local_outcode |= MGL_CLIP_TOP;
- }
-
- if (-cw > v->bz)
- {
- local_outcode |= MGL_CLIP_BACK;
- }
- else if (v->bz > cw)
- {
- local_outcode |= MGL_CLIP_FRONT;
- }
-
- v->outcode = local_outcode;
-
- } while (i--);
-
- #undef CLIP_EPS
- #undef a
- }
- }
-
-
- //following 5 functions are called from glLockArrays
- //05-04-02 returns number of onscreen verts
-
- INLINE ULONG TransformRange(GLcontext context, const int first, const int size)
- {
- int i;
- ULONG border;
-
- #define a(x) (context->CombinedMatrix.v[OF_##x])
-
- if(context->ArrayPointer.FixpointTrans == GL_TRUE)
- {
- static int m[16];
- int tx,ty,tz,tw;
- int x,y,z;
- int cw;
- int *vp;
- ULONG local_outcode;
- UBYTE *vpointer;
- MGLVertex *v;
- int stride;
-
- #define CLIP_EPS ((int)((1e-7)*32768.f))
-
- #define b(x) (m[OF_##x])
-
- if(context->CombinedValid == GL_FALSE)
- {
- const float float2fix = 32768.f;
-
- m_CombineMatrices(context);
-
- b(11)=(int)(a(11)*float2fix);
- b(12)=(int)(a(12)*float2fix);
- b(13)=(int)(a(13)*float2fix);
- b(14)=(int)(a(14)*float2fix);
- b(21)=(int)(a(21)*float2fix);
- b(22)=(int)(a(22)*float2fix);
- b(23)=(int)(a(23)*float2fix);
- b(24)=(int)(a(24)*float2fix);
- b(31)=(int)(a(31)*float2fix);
- b(32)=(int)(a(32)*float2fix);
- b(33)=(int)(a(33)*float2fix);
- b(34)=(int)(a(34)*float2fix);
- b(41)=(int)(a(41)*float2fix);
- b(42)=(int)(a(42)*float2fix);
- b(43)=(int)(a(43)*float2fix);
- b(44)=(int)(a(44)*float2fix);
- }
-
- stride = context->ArrayPointer.vertexstride;
- vpointer = (context->ArrayPointer.verts + first*stride);
-
- v = &(context->VertexBuffer[first]);
-
- border = 0;
- i = size;
-
- do
- {
-
- vp = (int *)vpointer;
-
- x = vp[0];
- y = vp[1];
- z = vp[2];
-
- //pipelined transformations
-
- tx = x*b(11);
- ty = x*b(21);
- tz = x*b(31);
- tw = x*b(41);
-
- tx += y*b(12);
- ty += y*b(22);
- tz += y*b(32);
- tw += y*b(42);
-
- tx += z*b(13);
- ty += z*b(23);
- tz += z*b(33);
- tw += z*b(43);
-
- tx += b(14);
- ty += b(24);
- tz += b(34);
- tw += b(44);
-
- local_outcode = 0;
-
- if (tw < CLIP_EPS )
- {
- local_outcode |= MGL_CLIP_NEGW;
- }
- if (-tw > tx)
- {
- local_outcode |= MGL_CLIP_LEFT;
- }
- else if (tx > tw)
- {
- local_outcode |= MGL_CLIP_RIGHT;
- }
-
- if (-tw > ty)
- {
- local_outcode |= MGL_CLIP_BOTTOM;
- }
- else if (ty > tw)
- {
- local_outcode |= MGL_CLIP_TOP;
- }
-
- if (-tw > tz)
- {
- local_outcode |= MGL_CLIP_BACK;
- }
- else if (tz > tw)
- {
- local_outcode |= MGL_CLIP_FRONT;
- }
-
- border |= local_outcode;
-
- v->outcode = local_outcode;
-
- v->bx = (float)tx;
- v->by = (float)ty;
- v->bz = (float)tz;
- v->bw = (float)tw;
-
- v++; vpointer += stride;
-
- } while (--i);
-
- #undef b
- #undef CLIP_EPS
- }
- else
- {
- float a11,a12,a13,a14;
- float a21,a22,a23,a24;
- float a31,a32,a33,a34;
- float a41,a42,a43,a44;
- float *vp;
- float cw;
- float x,y,z;
- ULONG local_outcode;
- UBYTE *vpointer;
- MGLVertex *v;
- int stride;
-
- #define CLIP_EPS (1e-7)
-
- if(context->CombinedValid == GL_FALSE)
- m_CombineMatrices(context);
-
- a11=a(11); a12=a(12); a13=a(13); a14=a(14);
- a21=a(21); a22=a(22); a23=a(23); a24=a(24);
- a31=a(31); a32=a(32); a33=a(33); a34=a(34);
- a41=a(41); a42=a(42); a43=a(43); a44=a(44);
-
- stride = context->ArrayPointer.vertexstride;
- vpointer = (context->ArrayPointer.verts + first*stride);
-
- v = &(context->VertexBuffer[first]);
-
- i = size;
-
- do
- {
- vp = (float *)vpointer;
-
- x = vp[0];
- y = vp[1];
- z = vp[2];
-
- v->bx = a11*x + a12*y + a13*z + a14;
- v->by = a21*x + a22*y + a23*z + a24;
- v->bz = a31*x + a32*y + a33*z + a34;
- v->bw = a41*x + a42*y + a43*z + a44;
-
- v++; vpointer += stride;
-
- } while (--i);
-
- v = &context->VertexBuffer[first];
- i = size;
- border = 0;
-
- do
- {
- cw = v->bw;
- local_outcode = 0;
-
- if (cw < CLIP_EPS )
- {
- local_outcode |= MGL_CLIP_NEGW;
- }
- if (-cw > v->bx)
- {
- local_outcode |= MGL_CLIP_LEFT;
- }
- else if (v->bx > cw)
- {
- local_outcode |= MGL_CLIP_RIGHT;
- }
-
- if (-cw > v->by)
- {
- local_outcode |= MGL_CLIP_BOTTOM;
- }
- else if (v->by > cw)
- {
- local_outcode |= MGL_CLIP_TOP;
- }
-
- if (-cw > v->bz)
- {
- local_outcode |= MGL_CLIP_BACK;
- }
- else if (v->bz > cw)
- {
- local_outcode |= MGL_CLIP_FRONT;
- }
-
- v->outcode = local_outcode;
-
- border |= local_outcode;
-
- v++;
- } while (--i);
-
- #undef CLIP_EPS
- }
-
- #undef a
-
- return border;
- }
-
-
- INLINE void ProjectRange(GLcontext context, const int first, const int size)
- {
- int i, stride;
- float x,y,z,w;
-
- UBYTE *pointer;
- float *wa;
- float az;
-
- if(context->ZOffset_State == GL_TRUE)
- {
- az = context->az + context->ZOffset;
- }
- else
- {
- az = context->az;
- }
-
- if(!(context->ClientState & GLCS_TEXTURE))
- {
- MGLVertex *v = &context->VertexBuffer[first];
- i = size;
-
- do
- {
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = 1.0 / v->bw;
-
- v->bx = context->ax + x * w * context->sx;
- v->by = context->ay - y * w * context->sy;
- v->bz = az + z * w * context->sz;
-
- v++;
-
- } while (--i);
- }
- else if (context->ArrayPointer.FixpointTrans == GL_TRUE)
- {
- MGLVertex *v = &context->VertexBuffer[first];
- stride = context->ArrayPointer.texcoordstride;
- pointer = (UBYTE*)context->WBuffer + first * stride;
-
-
- i = size;
-
- do
- {
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = 1.0 / v->bw;
-
- v->bx = context->ax + x * w * context->sx;
- v->by = context->ay - y * w * context->sy;
- v->bz = az + z * w * context->sz;
-
- w *= 32768.f;
- wa = (float*)pointer;
- *wa = w;
-
- v++;
- pointer += stride;
-
- } while (--i);
- }
- else
- {
- MGLVertex *v = &context->VertexBuffer[first];
- stride = context->ArrayPointer.texcoordstride;
- pointer = (UBYTE*)context->WBuffer + first * stride;
-
-
- i = size;
-
- do
- {
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = 1.0 / v->bw;
-
- v->bx = context->ax + x * w * context->sx;
- v->by = context->ay - y * w * context->sy;
- v->bz = az + z * w * context->sz;
-
- wa = (float*)pointer;
- *wa = w;
-
- v++;
- pointer += stride;
-
- } while (--i);
- }
- }
-
-
- INLINE void ProjectRangeByOutcode(GLcontext context, const int first, const int size)
- {
- int i, stride;
- float x,y,z,w;
-
- UBYTE *pointer;
- float *wa;
- float az;
-
- if(context->ZOffset_State == GL_TRUE)
- {
- az = context->az + context->ZOffset;
- }
- else
- {
- az = context->az;
- }
-
- if(context->ArrayPointer.FixpointTrans == GL_TRUE)
- {
- const float fix2float = 1.f/32768.f;
-
- if(!(context->ClientState & GLCS_TEXTURE))
- {
- MGLVertex *v = &context->VertexBuffer[first];
-
- for (i=0; i<size; i++, v++)
- {
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = v->bw;
-
- v->bx = fix2float * x;
- v->by = fix2float * y;
- v->bz = fix2float * z;
- v->bw = fix2float * w;
-
- if(v->outcode & context->ClipFlags)
- continue;
-
- w = 1.0 / w;
-
- v->v.x = context->ax + x * w * context->sx;
- v->v.y = context->ay - y * w * context->sy;
- v->v.z = az + z * w * context->sz;
- }
- }
- else
- {
- MGLVertex *v = &context->VertexBuffer[first];
- stride = context->ArrayPointer.texcoordstride;
- pointer = (UBYTE*)context->WBuffer + first * stride;
-
- for (i=0; i<size; i++, v++, pointer += stride)
- {
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = v->bw;
-
- v->bx = fix2float * x;
- v->by = fix2float * y;
- v->bz = fix2float * z;
- v->bw = fix2float * w;
-
- if(v->outcode & context->ClipFlags)
- continue;
-
- w = 1.0 / w;
-
- v->v.x = context->ax + x * w * context->sx;
- v->v.y = context->ay - y * w * context->sy;
- v->v.z = az + z * w * context->sz;
-
- w *= 32768.f;
- wa = (float*)pointer;
- v->v.w = w;
- *wa = w;
- }
- }
- }
- else if(!(context->ClientState & GLCS_TEXTURE))
- {
- MGLVertex *v = &context->VertexBuffer[first];
-
- for (i=0; i<size; i++, v++)
- {
- if(v->outcode & context->ClipFlags)
- continue;
-
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = 1.0 / v->bw;
-
- v->v.x = context->ax + x * w * context->sx;
- v->v.y = context->ay - y * w * context->sy;
- v->v.z = az + z * w * context->sz;
- }
- }
- else
- {
- MGLVertex *v = &context->VertexBuffer[first];
- stride = context->ArrayPointer.texcoordstride;
- pointer = (UBYTE*)context->WBuffer + first * stride;
-
- for (i=0; i<size; i++, v++, pointer += stride)
- {
- if(v->outcode & context->ClipFlags)
- continue;
-
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = 1.0 / v->bw;
-
- v->v.x = context->ax + x * w * context->sx;
- v->v.y = context->ay - y * w * context->sy;
- v->v.z = az + z * w * context->sz;
-
- v->v.w = w;
-
- wa = (float*)pointer;
- *wa = w;
- }
- }
- }
-
-
- INLINE void E_ToScreenArray(GLcontext context, const int count, const UWORD *idx)
- {
- int i, stride;
- float x,y,z,w;
-
- UBYTE *pointer;
- float *wa;
- float az;
-
- if(context->ZOffset_State == GL_TRUE)
- {
- az = context->az + context->ZOffset;
- }
- else
- {
- az = context->az;
- }
-
- if(!(context->ClientState & GLCS_TEXTURE))
- {
- i = 0;
-
- do
- {
- MGLVertex *v = &context->VertexBuffer[idx[i]];
-
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = 1.0 / v->bw;
-
- v->v.x = context->ax + x * w * context->sx;
- v->v.y = context->ay - y * w * context->sy;
- v->v.z = az + z * w * context->sz;
-
- i++;
- } while (i < count);
- }
- else
- {
- stride = context->ArrayPointer.texcoordstride;
-
- i = 0;
-
- do
- {
- MGLVertex *v = &context->VertexBuffer[idx[i]];
-
- x = v->bx;
- y = v->by;
- z = v->bz;
- w = 1.0 / v->bw;
-
- v->v.x = context->ax + x * w * context->sx;
- v->v.y = context->ay - y * w * context->sy;
- v->v.z = az + z * w * context->sz;
-
- pointer = (UBYTE*)context->WBuffer + idx[i] * stride;
- wa = (float*)pointer;
- *wa = w;
-
- i++;
- } while (i < count);
- }
- }
-
- INLINE void E_ToScreen(GLcontext context, int vnum)
- {
- float *wa;
- float w = 1.0/context->VertexBuffer[vnum].bw;
- UBYTE *pointer = (UBYTE*)context->WBuffer + vnum * context->ArrayPointer.texcoordstride;
-
- context->VertexBuffer[vnum].v.x = context->ax + context->VertexBuffer[vnum].bx * w * context->sx;
- context->VertexBuffer[vnum].v.y = context->ay - context->VertexBuffer[vnum].by * w * context->sy;
- context->VertexBuffer[vnum].v.z = context->az + context->VertexBuffer[vnum].bz * w * context->sz;
-
- if (context->ZOffset_State == GL_TRUE)
- context->VertexBuffer[vnum].v.z += (W3D_Float)context->ZOffset;
-
- context->VertexBuffer[vnum].v.w = w;
-
- wa = (float*)pointer;
- *wa = w;
- }
-
- #ifdef __VBCC__
-
- #define V_ToScreen(ctx,vnum){\
- static float wdiv;\
- wdiv = 1.0 / ctx->VertexBuffer[vnum].bw; \
- ctx->VertexBuffer[vnum].v.x = ctx->ax + ctx->VertexBuffer[vnum].bx * wdiv * ctx->sx; \
- ctx->VertexBuffer[vnum].v.y = ctx->ay - ctx->VertexBuffer[vnum].by * wdiv * ctx->sy; \
- ctx->VertexBuffer[vnum].v.z = ctx->az + ctx->VertexBuffer[vnum].bz * wdiv * ctx->sz; \
- if (ctx->ZOffset_State == GL_TRUE) ctx->VertexBuffer[vnum].v.z += (W3D_Float)ctx->ZOffset; \
- ctx->VertexBuffer[vnum].v.w = wdiv; \
- }
-
- #else
-
- static INLINE void V_ToScreen(GLcontext context, int vnum)
- {
- GLfloat wdiv = 1.f / context->VertexBuffer[vnum].bw;
-
- context->VertexBuffer[vnum].v.x = (W3D_Float)(context->ax + context->VertexBuffer[vnum].bx * wdiv * context->sx);
-
- context->VertexBuffer[vnum].v.y = (W3D_Float)(context->ay - context->VertexBuffer[vnum].by * wdiv * context->sy);
-
- context->VertexBuffer[vnum].v.z = (W3D_Float)(context->az + context->VertexBuffer[vnum].bz * wdiv * context->sz);
-
- if (context->ZOffset_State == GL_TRUE) context->VertexBuffer[vnum].v.z += (W3D_Float)context->ZOffset; \
-
- context->VertexBuffer[vnum].v.w = (W3D_Float)wdiv; \
- }
-
- #endif
-
- void E_DrawPoints(GLcontext context, const int count, const UWORD *idx)
- {
- }
-
- void E_DrawLines(GLcontext context, const int count, const UWORD *idx)
- {
- }
-
- void E_DrawLineStrip(GLcontext context, const int count, const UWORD *idx)
- {
- }
-
- void E_DrawLineLoop(GLcontext context, const int count, const UWORD *idx)
- {
- }
-
- void E_DrawQuads(GLcontext context, const int count, const UWORD *idx)
- {
- }
-
- void E_DrawQuadStrip(GLcontext context, const int count, const UWORD *idx)
- {
- }
-
-
- void E_DrawTriFan(GLcontext context, const int count, UWORD *idx)
- {
- int i,j;
- int size;
- ULONG and_code, or_code, guard_band;
- ULONG local_or, local_and;
- ULONG error;
- static W3D_Vertex **verts = NULL;
- static W3D_TrianglesV fan;
- static ULONG complete[MGL_MAXVERTS];
- static GLboolean visible[MGL_MAXVERTS];
- static GLboolean projected[4096];
- int first, triangle;
- int cnum, pnum, backface, prevcopy, free;
- int sign;
-
-
- if(Clip_Volume_Bypass != GL_FALSE)
- {
- size = count;
-
- //first check if we are in guardband-mode
- //and discard/shrink offscreen primitives
-
- if((Clip_Volume_Bypass > GL_TRUE) && context->VertexBuffer[idx[0]].outcode)
- {
- i = size - 2;
-
- local_and = context->VertexBuffer[idx[0]].outcode & context->VertexBuffer[idx[i]].outcode & context->VertexBuffer[idx[i+1]].outcode;
-
- if(local_and)
- {
- i--;
-
- while (i)
- {
- if((local_and & context->VertexBuffer[idx[i]].outcode) == 0)
- break;
- i--;
- }
- }
-
- if(i == 0)
- return;
-
- size = i+2;
- }
-
-
- if(context->CullFace_State == GL_FALSE)
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, size, (void*)idx);
- }
- else
- {
- float fsign;
- float area;
- float x1,x2;
- float y1,y2;
-
- #define x(a) (context->VertexBuffer[idx[a]].bx)
- #define y(a) (context->VertexBuffer[idx[a]].by)
-
-
- first = 0;
- backface = 0;
-
- fsign = (float)(-context->CurrentCullSign);
-
- if(size == 3)
- {
- x1 = x(1) - x(0);
- y1 = y(1) - y(0);
- x2 = x(2) - x(0);
- y2 = y(2) - y(0);
-
- area = y2*x1 - x2*y1;
- area *= fsign;
- }
- else
- {
- float x0,y0;
- float area2;
-
- x0 = x(0);
- y0 = y(0);
-
- x1 = x(1) - x0;
- y1 = y(1) - y0;
- x2 = x(2) - x0;
- y2 = y(2) - y0;
-
- area = y2*x1 - x2*y1;
- area *= fsign;
-
- if(area < 0.f)
- {
- first++;
- area = 0.f;
- }
-
- i = 1;
- do
- {
- x1 = x2;
- y1 = y2;
- x2 = x(i+2) - x0;
- y2 = y(i+2) - y0;
-
- area2 = y2*x1 - x2*y1;
- area2 *= fsign;
-
- if(area2 < 0.f)
- {
- if(first == i)
- first++;
- else
- backface++;
- }
- else
- {
- backface = 0;
- area += area2;
- }
-
- i++;
- } while (i < size-2);
- }
-
- if(area < context->MinTriArea)
- return;
-
- size -= backface + first; //shrink
-
- if(first)
- {
- UWORD val = idx[first];
-
- idx[first] = idx[0];
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, size, (void*)&idx[first]);
-
- idx[first] = val;
- }
- else
- {
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, size, (void*)idx);
-
- }
-
- #undef x
- #undef y
- }
- return;
- }
-
- sign = context->CurrentCullSign;
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- TransformIndex(context, count, idx);
- }
-
-
- or_code = 0;
- and_code = 0xff;
-
- for(i=0; i<count; i++)
- {
- and_code &= context->VertexBuffer[idx[i]].outcode;
- or_code |= context->VertexBuffer[idx[i]].outcode;
- }
-
- if(and_code)
- return;
-
- if(or_code == 0 || (or_code & context->ClipFlags))
- {
- guard_band = or_code;
- }
- else
- {
- float gcw;
- ULONG guard_code;
- MGLVertex *v;
-
- i = 0;
- guard_band = 0;
-
- do
- {
- v = &context->VertexBuffer[idx[i]];
-
- if(v->outcode)
- {
- gcw = v->bw * 2.0;
- guard_code = 0;
-
- if (-gcw > v->bx)
- guard_code |= MGL_CLIP_LEFT;
- else if (v->bx > gcw)
- guard_code |= MGL_CLIP_RIGHT;
-
- if (-gcw > v->by)
- guard_code |= MGL_CLIP_BOTTOM;
- else if (v->by > gcw)
- guard_code |= MGL_CLIP_TOP;
-
- guard_band |= guard_code;
- }
-
- i++;
- } while (i < count && guard_band == 0);
- }
-
- if (guard_band == 0)
- {
- if(context->ArrayPointer.transformed == GL_FALSE)
- E_ToScreenArray(context, count, idx);
-
- if(context->CullFace_State == GL_FALSE)
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, count, (void*)idx);
- }
- else
- {
- float fsign;
- float area;
- float x1,x2;
- float y1,y2;
-
- #define x(a) (context->VertexBuffer[idx[a]].v.x)
- #define y(a) (context->VertexBuffer[idx[a]].v.y)
-
-
- fsign = (float)(-context->CurrentCullSign);
-
- first = 0;
- size = count;
- backface = 0;
-
- if(size == 3)
- {
- x1 = x(1) - x(0);
- y1 = y(1) - y(0);
- x2 = x(2) - x(0);
- y2 = y(2) - y(0);
-
- area = y2*x1 - x2*y1;
- area *= fsign;
- }
- else
- {
- float x0,y0;
- float area2;
-
- x0 = x(0);
- y0 = y(0);
-
- x1 = x(1) - x0;
- y1 = y(1) - y0;
- x2 = x(2) - x0;
- y2 = y(2) - y0;
-
- area = y2*x1 - x2*y1;
- area *= fsign;
-
- if(area < 0.f)
- {
- first++;
- area = 0.f;
- }
-
- i = 1;
- do
- {
- x1 = x2;
- y1 = y2;
- x2 = x(i+2) - x0;
- y2 = y(i+2) - y0;
-
- area2 = y2*x1 - x2*y1;
- area2 *= fsign;
-
- if(area2 < 0.f)
- {
- if(first == i)
- first++;
- else
- backface++;
- }
- else
- {
- backface = 0;
- area += area2;
- }
-
- i++;
- } while (i < size-2);
- }
-
- if(area < context->MinTriArea)
- return;
-
- size -= backface + first; //shrink
-
- if(first)
- {
- UWORD val = idx[first];
-
- idx[first] = idx[0];
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, size, (void*)&idx[first]);
-
- idx[first] = val;
- }
- else
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, size, (void*)idx);
- }
-
- #undef x
- #undef y
- }
-
- return;
- }
-
-
- if (verts == NULL)
- {
- verts = (W3D_Vertex **)malloc(sizeof(W3D_Vertex *) * context->VertexBufferSize);
- if (!verts) return;
- }
-
-
- backface = 0;
- triangle = 0;
- i = 1;
-
- if(context->CullFace_State == GL_FALSE)
- {
- do
- {
- local_and = context->VertexBuffer[idx[0]].outcode
- & context->VertexBuffer[idx[i]].outcode
- & context->VertexBuffer[idx[i+1]].outcode;
-
- local_or = context->VertexBuffer[idx[0]].outcode
- | context->VertexBuffer[idx[i]].outcode
- | context->VertexBuffer[idx[i+1]].outcode;
-
-
- if (local_and == 0) // if the local and code is zero, we're not
- {
- complete[triangle] = local_or;
- visible[triangle] = GL_TRUE;
- backface = 0;
- }
- else
- {
- visible[triangle] = GL_FALSE;
- backface++;
- }
- i++;
- triangle++;
- } while ( i< count-1);
- }
- else
- {
- do
- {
- local_and = context->VertexBuffer[idx[0]].outcode
- & context->VertexBuffer[idx[i]].outcode
- & context->VertexBuffer[idx[i+1]].outcode;
-
- local_or = context->VertexBuffer[idx[0]].outcode
- | context->VertexBuffer[idx[i]].outcode
- | context->VertexBuffer[idx[i+1]].outcode;
-
-
- if (local_and == 0) // if the local and code is zero, we're not
- {
- complete[triangle] = local_or;
-
- if(local_or & MGL_CLIP_NEGW)
- {
- visible[triangle] = GL_TRUE;
- backface = 0;
- }
- else
- {
- visible[triangle] = DecideFrontface(context, &(context->VertexBuffer[idx[0]]), &(context->VertexBuffer[idx[i]]), &(context->VertexBuffer[idx[i+1]]), sign);
-
- if(!visible[triangle])
- backface++;
- else
- backface = 0;
- }
- }
- else
- {
- visible[triangle] = GL_FALSE;
- backface++;
- }
- i++;
- triangle++;
- } while ( i< count-1);
- }
-
- if(backface == triangle) //early out
- return;
-
- size = count - backface;
-
- Convert(context, idx[0]);
-
- prevcopy = 0;
- pnum = 0;
- cnum = 0;
- free = context->VertexBufferPointer;
- triangle = 0; i = 1;
-
- do
- {
- if (visible[triangle] == GL_FALSE) // case 3
- {
- triangle ++;
- i ++;
- }
- else
- {
-
- if (complete[triangle]) // case 1
- {
- clip[cnum].numverts = 3;
- clip[cnum].verts[0] = idx[0];
- clip[cnum].verts[1] = idx[i];
- clip[cnum].verts[2] = idx[i+1];
-
- if(prevcopy != i)
- Convert(context, idx[i]);
-
- Convert(context, idx[i+1]);
- prevcopy = i+1;
-
- AE_ClipPoly(context, &clip[cnum], free, complete[triangle]);
-
- if(clip[cnum].numverts)
- {
- free = clip[cnum].nextfree;
- cnum++;
- }
-
- triangle++; i++;
- }
- else
- { // case 2 (the difficult part)
- int k=3;
- polys[pnum].verts[0] = idx[0];
- polys[pnum].verts[1] = idx[i];
- polys[pnum].verts[2] = idx[i+1];
-
- triangle++; i++;
-
- while (complete[triangle]==0 && visible[triangle] && i<size-1)
- {
- polys[pnum].verts[k] = idx[i+1];
-
- i++; k++; triangle++;
- }
-
- polys[pnum].numverts = k;
- pnum++;
- }
- }
- } while (i<size-1);
-
-
- //Project to screen and draw:
-
- if(cnum)
- {
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- for(i=0; i<size; i++)
- {
- projected[idx[i]] = GL_FALSE;
- }
- }
-
- for(i=context->VertexBufferPointer; i<free; i++)
- {
- V_ToScreen(context, i);
- }
-
- }
-
- if(pnum)
- {
- PolyBuffer *p;
-
- p = &polys[0];
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- E_ToScreen(context, p->verts[0]);
- E_ToScreen(context, p->verts[1]);
- E_ToScreen(context, p->verts[2]);
-
- projected[p->verts[0]] = GL_TRUE;
- projected[p->verts[1]] = GL_TRUE;
- projected[p->verts[2]] = GL_TRUE;
-
- if(p->numverts > 3)
- {
- i=3;
- do
- {
- E_ToScreen(context, p->verts[i]);
- projected[p->verts[i]] = GL_TRUE;
- i++;
- } while (i < p->numverts);
- }
- }
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_ULONG, p->numverts, (void*)p->verts);
-
- j = 1;
- while (j < pnum)
- {
- p = &polys[j];
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- E_ToScreen(context, p->verts[1]);
- E_ToScreen(context, p->verts[2]);
-
- projected[p->verts[1]] = GL_TRUE;
- projected[p->verts[2]] = GL_TRUE;
-
-
- if(p->numverts > 3)
- {
- i=3;
-
- do
- {
- E_ToScreen(context, p->verts[i]);
- projected[p->verts[i]] = GL_TRUE;
- i++;
- } while (i < p->numverts);
- }
- }
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_ULONG, p->numverts, (void*)p->verts);
-
- j++;
- }
- }
-
- if(cnum)
- {
- fan.tex = context->w3dTexBuffer[context->CurrentBinding];
- fan.st_pattern = NULL;
-
- j = 0;
-
- do
- {
- PolyBuffer *p = &clip[j];
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- for (i=0; i<p->numverts; i++)
- {
- int vert = p->verts[i];
-
- verts[i] = &(context->VertexBuffer[vert].v);
-
- if(vert < context->VertexBufferPointer && projected[vert] == GL_FALSE)
- {
- V_ToScreen(context, vert);
- projected[vert] = GL_TRUE;
- }
-
- }
- }
- else
- {
- for (i=0; i<p->numverts; i++)
- {
- verts[i] = &(context->VertexBuffer[p->verts[i]].v);
- }
- }
-
- fan.vertexcount = p->numverts;
- fan.v = verts;
- error = W3D_DrawTriFanV(context->w3dContext, &fan);
-
- j++;
-
- } while (j < cnum);
- }
- }
-
-
- void E_DrawTriStrip(GLcontext context, const int count, const UWORD *idx)
- {
- int i,j;
- int size;
- ULONG and_code, or_code, guard_band;
- ULONG local_or, local_and;
- ULONG error;
- static W3D_Vertex **verts = NULL;
- static W3D_TrianglesV tris;
- static ULONG complete[MGL_MAXVERTS];
- static GLboolean visible[MGL_MAXVERTS];
- static GLboolean projected[4096];
- int first;
- int cnum, pnum, backface, prevcopy, free;
-
-
- if(Clip_Volume_Bypass != GL_FALSE)
- {
- size = count;
- first = 0;
-
- //first check if we are in guardband-mode
- //and discard/shrink offscreen primitives
-
- if((Clip_Volume_Bypass > GL_TRUE) && (context->VertexBuffer[idx[0]].outcode || context->VertexBuffer[idx[size-1]].outcode))
- {
- i = size - 3;
-
- local_and = context->VertexBuffer[idx[i]].outcode & context->VertexBuffer[idx[i+1]].outcode & context->VertexBuffer[idx[i+2]].outcode;
-
- if(local_and)
- {
- i--;
-
- while (i >= 0)
- {
- if((local_and & context->VertexBuffer[idx[i]].outcode) == 0)
- break;
- i--;
- }
- }
-
- if(i < 0)
- return;
-
- size = i+3;
-
- if(size > 3)
- {
- local_and = context->VertexBuffer[idx[0]].outcode & context->VertexBuffer[idx[1]].outcode & context->VertexBuffer[idx[2]].outcode;
-
- i = 2;
-
- if(local_and)
- {
- i++;
-
- while(i < size-1)
- {
- if((local_and & context->VertexBuffer[idx[i]].outcode) == 0)
- break;
- i++;
-
- }
- }
-
- first = i-2;
- }
- }
-
- if(context->CullFace_State == GL_FALSE)
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRISTRIP, W3D_INDEX_UWORD, size-first, (void*)&idx[first]);
- }
- else
- {
- float fsign;
- float area;
- float x1,x2;
- float y1,y2;
-
- #define x(a) (context->VertexBuffer[idx[a]].bx)
- #define y(a) (context->VertexBuffer[idx[a]].by)
-
- backface = 0;
-
- fsign = (float)(-context->CurrentCullSign);
- if(first % 2) fsign = -fsign;
-
- if(size == 3)
- {
- x1 = x(first+1) - x(first);
- y1 = y(first+1) - y(first);
- x2 = x(first+2) - x(first);
- y2 = y(first+2) - y(first);
-
- area = y2*x1 - x2*y1;
- area *= fsign;
- }
- else
- {
- float a1,a2,b1,b2;
- float area2;
-
- i = first+1;
-
- a1 = x(i);
- b1 = y(i);
- a2 = x(i+1);
- b2 = y(i+1);
-
- x1 = a1 - x(first);
- y1 = b1 - y(first);
- x2 = a2 - x(first);
- y2 = b2 - y(first);
-
- area = y2*x1 - x2*y1;
- area *= fsign;
-
-
- if(area < 0.f)
- {
- first++;
- area = 0.f;
- }
-
-
- do
- {
- fsign = -fsign;
-
- x1 = a2 - a1;
- y1 = b2 - b1;
- x2 = x(i+2) - a1;
- y2 = y(i+2) - b1;
- a1 = a2;
- b1 = b2;
- a2 = x(i+2);
- b2 = y(i+2);
-
- area2 = y2*x1 - x2*y1;
- area2 *= fsign;
-
- if(area2 < 0.f)
- {
- if(first == i)
- first++;
- else
- backface++;
- }
- else
- {
- backface = 0;
- area += area2;
- }
-
- i++;
- } while (i < size-2);
-
- size -= backface + first;
- }
-
- if(area < context->MinTriArea)
- return;
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRISTRIP, W3D_INDEX_UWORD, size, (void*)&idx[first]);
-
- #undef x
- #undef y
- }
- return;
- }
-
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- TransformIndex(context, count, idx);
- }
-
- or_code = 0;
- and_code = 0xff;
-
- for(i=0; i<count; i++)
- {
- and_code &= context->VertexBuffer[idx[i]].outcode;
- or_code |= context->VertexBuffer[idx[i]].outcode;
- }
-
- if(and_code)
- return;
-
- if(or_code == 0 || (or_code & context->ClipFlags))
- {
- guard_band = or_code;
- }
- else
- {
- float gcw;
- ULONG guard_code;
- MGLVertex *v;
-
- i = 0;
- guard_band = 0;
-
- do
- {
- v = &context->VertexBuffer[idx[i]];
-
- if(v->outcode)
- {
- gcw = v->bw * 2.0;
- guard_code = 0;
-
- if (-gcw > v->bx)
- guard_code |= MGL_CLIP_LEFT;
- else if (v->bx > gcw)
- guard_code |= MGL_CLIP_RIGHT;
-
- if (-gcw > v->by)
- guard_code |= MGL_CLIP_BOTTOM;
- else if (v->by > gcw)
- guard_code |= MGL_CLIP_TOP;
-
- guard_band |= guard_code;
- }
-
- i++;
- } while (i < count && guard_band == 0);
- }
-
- if (guard_band == 0)
- {
- if(context->ArrayPointer.transformed == GL_FALSE)
- E_ToScreenArray(context, count, idx);
-
- if(context->CullFace_State == GL_FALSE)
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRISTRIP, W3D_INDEX_UWORD, count, (void*)idx);
-
- }
- else
- {
- #define x(a) (context->VertexBuffer[idx[a]].v.x)
- #define y(a) (context->VertexBuffer[idx[a]].v.y)
-
- float fsign;
- float area;
- float x1,x2;
- float y1,y2;
-
- fsign = (float)(-context->CurrentCullSign);
-
- size = count;
- backface = 0;
- first = 0;
-
-
- if(size == 3)
- {
- x1 = x(1) - x(0);
- y1 = y(1) - y(0);
- x2 = x(2) - x(0);
- y2 = y(2) - y(0);
-
- area = y2*x1 - x2*y1;
- area *= fsign;
- }
- else
- {
- float a1,a2,b1,b2;
- float area2;
-
- a1 = x(1);
- b1 = y(1);
- a2 = x(2);
- b2 = y(2);
-
- x1 = a1 - x(0);
- y1 = b1 - y(0);
- x2 = a2 - x(0);
- y2 = b2 - y(0);
-
- area = y2*x1 - x2*y1;
- area *= fsign;
-
- if(area < 0.f)
- {
- first++;
- area = 0.f;
- }
-
- i = 1;
- do
- {
- fsign = -fsign;
- x1 = a2 - a1;
- y1 = b2 - b1;
- x2 = x(i+2) - a1;
- y2 = y(i+2) - b1;
- a1 = a2;
- b1 = b2;
- a2 = x(i+2);
- b2 = y(i+2);
-
- area2 = y2*x1 - x2*y1;
- area2 *= fsign;
-
- if(area2 < 0.f)
- {
- if(first == i)
- first++;
- else
- backface++;
- }
- else
- {
- backface = 0;
- area += area2;
- }
-
- i++;
- } while (i < size-2);
-
- size -= first + backface;
- }
-
- if(area < context->MinTriArea)
- return;
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRISTRIP, W3D_INDEX_UWORD, size, (void*)&idx[first]);
-
- #undef x
- #undef y
-
- }
-
- return;
- }
-
-
- if (verts == NULL)
- {
- verts = (W3D_Vertex **)malloc(sizeof(W3D_Vertex *) * context->VertexBufferSize);
- if (!verts) return;
- }
-
-
- backface = 0;
- i = 0;
-
- do
- {
- local_and = context->VertexBuffer[idx[i]].outcode
- & context->VertexBuffer[idx[i+1]].outcode
- & context->VertexBuffer[idx[i+2]].outcode;
-
- local_or = context->VertexBuffer[idx[i]].outcode
- | context->VertexBuffer[idx[i+1]].outcode
- | context->VertexBuffer[idx[i+2]].outcode;
-
- if (local_and == 0) // if the local and code is zero, we're not
- {
- complete[i] = local_or;
- visible[i] = GL_TRUE;
- backface = 0;
- }
- else
- {
- visible[i] = GL_FALSE;
- backface++;
- }
-
- i++;
- } while (i < count-2);
-
- size = count - backface;
-
- free = context->VertexBufferPointer;
-
- prevcopy = -1;
- pnum = 0;
- cnum = 0;
- i = 0;
-
- do
- {
- if (visible[i] == GL_FALSE) // case 3
- {
- i++;
- }
- else if (complete[i]) // case 1
- {
- clip[cnum].numverts = 3;
-
- clip[cnum].verts[0] = idx[i];
- clip[cnum].verts[1] = idx[i+1];
- clip[cnum].verts[2] = idx[i+2];
-
- //this element is never shared with next triangle:
-
- if(prevcopy == i+1)
- {
- Convert(context, idx[i+2]);
- }
- else if(prevcopy == i)
- {
- Convert(context, idx[i+1]);
- Convert(context, idx[i+2]);
- }
- else
- {
- Convert(context, idx[i+0]);
- Convert(context, idx[i+1]);
- Convert(context, idx[i+2]);
- }
-
- //this element is never shared with previous triangle:
-
- prevcopy = i+2;
-
-
- AE_ClipPoly(context, &clip[cnum], free, complete[i]);
- i++;
-
- if(clip[cnum].numverts)
- {
- free = clip[cnum].nextfree;
- cnum++;
- }
- }
- else
- { // case 2 (the difficult part)
-
- int k = 3;
- polys[pnum].verts[0] = i;
- i++;
-
- while (complete[i]==0 && visible[i] == GL_TRUE && i<size-2 && k < 64)
- {
- i++; k++;
- }
-
- polys[pnum].numverts = k;
- pnum++;
- }
- } while (i < size-2);
-
-
- //Project to screen and draw:
-
- if(cnum)
- {
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- for(i=0; i<size; i++)
- {
- projected[idx[i]] = GL_FALSE;
- }
- }
-
- for(i=context->VertexBufferPointer; i<free; i++)
- {
- V_ToScreen(context, i);
- }
- }
-
- if(pnum)
- {
- PolyBuffer *p;
- int start;
-
- p = &polys[0];
- start = p->verts[0];
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- E_ToScreen(context, idx[start+0]);
- E_ToScreen(context, idx[start+1]);
- E_ToScreen(context, idx[start+2]);
-
- projected[idx[start+0]] = GL_TRUE;
- projected[idx[start+1]] = GL_TRUE;
- projected[idx[start+2]] = GL_TRUE;
-
- i=3;
- while(i < p->numverts)
- {
- E_ToScreen(context, idx[start+i]);
- projected[idx[start+i]] = GL_TRUE;
- i++;
- }
- }
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRISTRIP, W3D_INDEX_UWORD, p->numverts, (void*)&idx[start]);
-
- j = 1;
-
- while (j < pnum)
- {
- p = &polys[j];
- start = p->verts[0];
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
-
- if(projected[idx[start+0]] == GL_FALSE)
- E_ToScreen(context, idx[start+0]);
-
- E_ToScreen(context, idx[start+1]);
- E_ToScreen(context, idx[start+2]);
-
- projected[idx[start+0]] = GL_TRUE;
- projected[idx[start+1]] = GL_TRUE;
- projected[idx[start+2]] = GL_TRUE;
-
- i=3;
- while(i < p->numverts)
- {
- E_ToScreen(context, idx[start+i]);
- projected[idx[start+i]] = GL_TRUE;
- i++;
- }
- }
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRISTRIP, W3D_INDEX_UWORD, p->numverts, (void*)&idx[start]);
-
- j++;
- }
- }
-
- if(cnum)
- {
- tris.tex = context->w3dTexBuffer[context->CurrentBinding];
- tris.st_pattern = NULL;
-
- j = 0;
-
- do
- {
- PolyBuffer *p = &clip[j];
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- for (i=0; i<p->numverts; i++)
- {
- int vert = p->verts[i];
-
- verts[i] = &(context->VertexBuffer[vert].v);
-
- if(vert < context->VertexBufferPointer && projected[vert] == GL_FALSE)
- {
- V_ToScreen(context, vert);
- projected[vert] = GL_TRUE;
- }
-
- }
- }
- else
- {
- for (i=0; i<p->numverts; i++)
- {
- verts[i] = &(context->VertexBuffer[p->verts[i]].v);
- }
- }
-
- tris.vertexcount = p->numverts;
- tris.v = verts;
-
- error = W3D_DrawTriFanV(context->w3dContext, &tris);
-
- j++;
- } while (j < cnum);
- }
- }
-
-
- //added 27-05-02
-
- void E_DrawTriangles_Locked(GLcontext context, const int count, const UWORD *idx)
- {
- int i, j;
- ULONG local_and, local_or;
- ULONG error;
- static W3D_Vertex **verts = NULL;
- static W3D_TrianglesV fan;
- static ULONG trichain[MGL_MAXVERTS*3];
- static int sign;
- GLboolean visible;
- int cnum, free, chainverts;
-
- sign = context->CurrentCullSign;
-
- if(Clip_Volume_Bypass != GL_FALSE)
- {
- chainverts = 0;
-
- if(Clip_Volume_Bypass == GL_TRUE)
- {
- if(context->CullFace_State == GL_FALSE)
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIANGLES, W3D_INDEX_UWORD, count, (void *)idx);
- }
- else
- {
- for(i=0; i<count; i+=3)
- {
- if(E_CheckTri(context, &context->VertexBuffer[idx[i]], &context->VertexBuffer[idx[i+1]], &context->VertexBuffer[idx[i+2]], sign) == GL_TRUE)
- {
- trichain[chainverts+0] = idx[i+0];
- trichain[chainverts+1] = idx[i+1];
- trichain[chainverts+2] = idx[i+2];
- chainverts+=3;
- }
- }
-
- }
- }
- else
- {
- if(context->CullFace_State == GL_FALSE)
- for(i=0; i<count; i+=3)
- {
- local_and = context->VertexBuffer[idx[i]].outcode & context->VertexBuffer[idx[i+1]].outcode & context->VertexBuffer[idx[i+2]].outcode;
-
- if(local_and == 0)
- {
-
- trichain[chainverts+0] = idx[i+0];
- trichain[chainverts+1] = idx[i+1];
- trichain[chainverts+2] = idx[i+2];
- chainverts+=3;
- }
- }
- else
- for(i=0; i<count; i+=3)
- {
- local_and = context->VertexBuffer[idx[i]].outcode & context->VertexBuffer[idx[i+1]].outcode & context->VertexBuffer[idx[i+2]].outcode;
-
- if(local_and == 0)
- {
-
- if(E_CheckTri(context, &context->VertexBuffer[idx[i]], &context->VertexBuffer[idx[i+1]], &context->VertexBuffer[idx[i+2]], sign) == GL_TRUE)
- {
- trichain[chainverts+0] = idx[i+0];
- trichain[chainverts+1] = idx[i+1];
- trichain[chainverts+2] = idx[i+2];
- chainverts+=3;
- }
- }
- }
- }
-
- if(chainverts)
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIANGLES, W3D_INDEX_ULONG, chainverts, (void *)trichain);
-
- return;
- }
-
- free = context->VertexBufferPointer;
- chainverts = 0;
- cnum = 0;
- i = 0;
-
- do
- {
- local_and = context->VertexBuffer[idx[i]].outcode & context->VertexBuffer[idx[i+1]].outcode & context->VertexBuffer[idx[i+2]].outcode;
-
- local_or = context->VertexBuffer[idx[i]].outcode | context->VertexBuffer[idx[i+1]].outcode | context->VertexBuffer[idx[i+2]].outcode;
-
- if(local_and)
- {
- i+=3;
- }
- else
- {
- if (local_or == 0)
- {
- if(context->CullFace_State == GL_FALSE)
- {
- visible = GL_TRUE;
- }
- else
- {
- visible = E_CheckTri(context, &context->VertexBuffer[idx[i]], &context->VertexBuffer[idx[i+1]], &context->VertexBuffer[idx[i+2]], sign);
- }
-
- if(visible)
- {
- trichain[chainverts+0] = idx[i+0];
- trichain[chainverts+1] = idx[i+1];
- trichain[chainverts+2] = idx[i+2];
- chainverts += 3;
- }
- }
- else
- {
- if(context->CullFace_State == GL_FALSE || (local_or & MGL_CLIP_NEGW))
- {
- visible = GL_TRUE;
- }
- else
- {
- visible = DecideFrontface(context, &(context->VertexBuffer[idx[i]]), &(context->VertexBuffer[idx[i+1]]), &(context->VertexBuffer[idx[i+2]]), sign);
- }
-
- if(visible)
- {
- Convert(context, idx[i]);
- Convert(context, idx[i+1]);
- Convert(context, idx[i+2]);
-
- clip[cnum].numverts = 3;
- clip[cnum].verts[0] = idx[i];
- clip[cnum].verts[1] = idx[i+1];
- clip[cnum].verts[2] = idx[i+2];
-
- AE_ClipPoly(context, &clip[cnum], free, local_or);
-
- if(clip[cnum].numverts)
- {
- free = clip[cnum].nextfree;
- cnum++;
- }
- }
- }
- i+=3;
- }
- } while (i < count);
-
-
- if(chainverts)
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIANGLES, W3D_INDEX_ULONG, chainverts, (void*)&trichain[0]);
- }
-
-
- if (cnum)
- {
- static PolyBuffer *p;
- static int start;
-
- if(verts == NULL)
- {
- verts = (W3D_Vertex **)malloc(sizeof(W3D_Vertex *) * context->VertexBufferSize);
- if (!verts) return;
- }
-
- for(i=context->VertexBufferPointer; i<free; i++)
- {
- V_ToScreen(context, i);
- }
-
- fan.st_pattern = NULL;
- fan.tex = context->w3dTexBuffer[context->CurrentBinding];
-
- start = 0;
- i = 0;
-
- do
- {
- p = &clip[i];
- j = 0;
-
- while (j < p->numverts)
- {
- verts[start+j] = &(context->VertexBuffer[p->verts[j]].v);
-
- j++;
- }
-
- fan.v = &verts[start];
- fan.vertexcount = p->numverts;
- start += p->numverts;
-
- error = W3D_DrawTriFanV(context->w3dContext, &fan);
- i++;
- } while (i < cnum);
- }
- }
-
-
- void E_DrawTriangles(GLcontext context, const int count, const UWORD *idx)
- {
- int i, j;
- ULONG local_and, local_or;
- ULONG error;
- static W3D_Vertex **verts = NULL;
- static W3D_TrianglesV fan;
- static ULONG trichain[MGL_MAXVERTS*3]; //should be enough
- static GLboolean visible;
- static int sign;
- int cnum, free, chainverts;
-
- if(context->ArrayPointer.transformed == GL_TRUE)
- {
- E_DrawTriangles_Locked(context, count, idx);
- return;
- }
-
- sign = context->CurrentCullSign;
-
- TransformIndex(context, count, idx);
-
- free = context->VertexBufferPointer;
- chainverts = 0;
- cnum = 0;
- i = 0;
-
- do
- {
- local_and = context->VertexBuffer[idx[i]].outcode & context->VertexBuffer[idx[i+1]].outcode & context->VertexBuffer[idx[i+2]].outcode;
-
- local_or = context->VertexBuffer[idx[i]].outcode | context->VertexBuffer[idx[i+1]].outcode | context->VertexBuffer[idx[i+2]].outcode;
-
- if(local_and)
- {
- i+=3;
- }
- else
- {
- if (local_or == 0)
- {
- E_ToScreen(context, idx[i]);
- E_ToScreen(context, idx[i+1]);
- E_ToScreen(context, idx[i+2]);
-
- if(context->CullFace_State == GL_FALSE)
- {
- visible = GL_TRUE;
- }
- else
- {
- visible = E_CheckTri(context, &context->VertexBuffer[idx[i]], &context->VertexBuffer[idx[i+1]], &context->VertexBuffer[idx[i+2]], sign);
- }
-
- if(visible)
- {
- trichain[chainverts+0] = idx[i+0];
- trichain[chainverts+1] = idx[i+1];
- trichain[chainverts+2] = idx[i+2];
- chainverts += 3;
- }
- }
- else
- {
- if(context->CullFace_State == GL_FALSE || (local_or & MGL_CLIP_NEGW))
- {
- visible = GL_TRUE;
- }
- else
- {
- visible = DecideFrontface(context, &(context->VertexBuffer[idx[i]]), &(context->VertexBuffer[idx[i+1]]), &(context->VertexBuffer[idx[i+2]]), sign);
- }
-
- if(visible)
- {
- Convert(context, idx[i]);
- Convert(context, idx[i+1]);
- Convert(context, idx[i+2]);
-
- clip[cnum].numverts = 3;
- clip[cnum].verts[0] = idx[i];
- clip[cnum].verts[1] = idx[i+1];
- clip[cnum].verts[2] = idx[i+2];
-
- AE_ClipPoly(context, &clip[cnum], free, local_or);
-
- if(clip[cnum].numverts)
- {
- free = clip[cnum].nextfree;
- cnum++;
- }
- }
- }
- i+=3;
- }
- } while (i < count);
-
-
- if(chainverts)
- {
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIANGLES, W3D_INDEX_ULONG, chainverts, (void*)&trichain[0]);
- }
-
-
- if (cnum)
- {
- static PolyBuffer *p;
- static int start;
-
- if(verts == NULL)
- {
- verts = (W3D_Vertex **)malloc(sizeof(W3D_Vertex *) * context->VertexBufferSize);
- if (!verts) return;
- }
-
- for(i=context->VertexBufferPointer; i<free; i++)
- {
- V_ToScreen(context, i);
- }
-
- fan.st_pattern = NULL;
- fan.tex = context->w3dTexBuffer[context->CurrentBinding];
-
- start = 0;
- i = 0;
-
- do
- {
- p = &clip[i];
- j = 0;
-
- while (j < p->numverts)
- {
- int vert = p->verts[j];
- verts[start+j] = &(context->VertexBuffer[vert].v);
-
- if(vert < context->VertexBufferPointer)
- {
- V_ToScreen(context, vert);
- }
- j++;
- }
-
- fan.v = &verts[start];
- fan.vertexcount = p->numverts;
-
- start += p->numverts;
-
- error = W3D_DrawTriFanV(context->w3dContext, &fan);
-
- i++;
- } while (i < cnum);
- }
- }
-
- void E_DrawPolygon(GLcontext context, const int count, UWORD *idx)
- {
- int i,j;
- ULONG error;
- ULONG and_code, or_code;
- PolyBuffer pclip;
- static W3D_Vertex **verts = NULL;
- static W3D_TrianglesV fan;
-
- if(Clip_Volume_Bypass != GL_FALSE)
- {
- int size = count;
-
- //first check if we are in guardband-mode
- //and discard offscreen primitives
-
- if((Clip_Volume_Bypass > GL_TRUE) && context->VertexBuffer[idx[0]].outcode)
- {
- ULONG local_and;
-
- i = size - 2;
-
- local_and = context->VertexBuffer[idx[0]].outcode & context->VertexBuffer[idx[i]].outcode & context->VertexBuffer[idx[i+1]].outcode;
-
- if(local_and)
- {
- i--;
-
- while (i)
- {
- if((local_and & context->VertexBuffer[idx[i]].outcode) == 0)
- break;
- i--;
- }
- }
-
- if(i == 0)
- return;
-
- size = i+2;
- }
-
- if(context->CullFace_State == GL_TRUE)
- {
- float x0,y0;
- float x1,y1;
- float x2,y2;
- GLfloat area;
-
- #define x(a) (context->VertexBuffer[idx[a]].v.x)
- #define y(a) (context->VertexBuffer[idx[a]].v.y)
-
- x0 = x(0);
- y0 = y(0);
- x1 = x(1) - x0;
- y1 = y(1) - y0;
- x2 = x(2) - x0;
- y2 = y(2) - y0;
-
- area = y2*x1 - x2*y1;
-
- i = 1;
-
- while (i < size-2)
- {
- x1 = x2;
- y1 = y2;
- x2 = x(i+2) - x0;
- y2 = y(i+2) - y0;
-
- area += y2*x1 - x2*y1;
- i++;
- }
-
- if(context->CurrentCullSign > 0)
- area = -area;
-
- if(area < context->MinTriArea)
- return;
-
- #undef x
- #undef y
- }
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, size, (void *)idx);
-
- return;
- }
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- TransformIndex(context, count, idx);
- }
-
- or_code = 0;
- and_code = 0xff;
-
- for(i=0; i<count; i++)
- {
- and_code &= context->VertexBuffer[idx[i]].outcode;
- or_code |= context->VertexBuffer[idx[i]].outcode;
- }
-
- if(and_code)
- return;
-
- if (or_code == 0)
- {
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- E_ToScreenArray(context, count, idx);
- }
-
- if(context->CullFace_State == GL_TRUE)
- {
- float x0,y0;
- float x1,y1;
- float x2,y2;
- GLfloat area;
-
- #define x(a) (context->VertexBuffer[idx[a]].v.x)
- #define y(a) (context->VertexBuffer[idx[a]].v.y)
-
- x0 = x(0);
- y0 = y(0);
- x1 = x(1) - x0;
- y1 = y(1) - y0;
- x2 = x(2) - x0;
- y2 = y(2) - y0;
-
- area = y2*x1 - x2*y1;
-
- i = 1;
-
- while (i < count-2 && fabs(area) < context->MinTriArea)
- {
- x1 = x2;
- y1 = y2;
- x2 = x(i+2) - x0;
- y2 = y(i+2) - y0;
-
- area += y2*x1 - x2*y1;
- i++;
- }
-
- if(context->CurrentCullSign > 0)
- area = -area;
-
- if(area < context->MinTriArea)
- return;
-
- #undef x
- #undef y
- }
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, count, (void *)idx);
-
- return;
- }
-
- if(verts == NULL)
- {
- verts = (W3D_Vertex **)malloc(sizeof(W3D_Vertex *) * context->VertexBufferSize);
- if (!verts) return;
- }
-
- i = 0;
- do
- {
- Convert(context, idx[i]);
- pclip.verts[i] = idx[i];
-
- i++;
- } while (i < count);
-
- pclip.numverts = count;
-
- AE_ClipPoly(context, &pclip, context->VertexBufferPointer, or_code);
-
- if(pclip.numverts < 3)
- return;
-
- for(i=context->VertexBufferPointer; i<pclip.nextfree; i++)
- {
- V_ToScreen(context, i);
- }
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- int vert;
-
- i = 0;
- do
- {
- vert = pclip.verts[i];
-
- if(vert > context->VertexBufferPointer)
- V_ToScreen(context, vert);
-
- verts[i] = &(context->VertexBuffer[vert].v);
-
- i++;
- } while (i < pclip.numverts);
- }
- else
- {
- i = 0;
- do
- {
- verts[i] = &(context->VertexBuffer[pclip.verts[i]].v);
-
- i++;
- } while (i < pclip.numverts);
- }
-
- if(context->CullFace_State == GL_TRUE)
- {
- float x0,y0;
- float x1,y1;
- float x2,y2;
- GLfloat area;
-
- #define x(a) (context->VertexBuffer[pclip.verts[a]].v.x)
- #define y(a) (context->VertexBuffer[pclip.verts[a]].v.y)
-
- x0 = x(0);
- y0 = y(0);
- x1 = x(1) - x0;
- y1 = y(1) - y0;
- x2 = x(2) - x0;
- y2 = y(2) - y0;
-
- area = y2*x1 - x2*y1;
-
- i = 1;
-
- while (i < pclip.numverts-2 && fabs(area) < context->MinTriArea)
- {
- x1 = x2;
- y1 = y2;
- x2 = x(i+2) - x0;
- y2 = y(i+2) - y0;
-
- area += y2*x1 - x2*y1;
- i++;
- }
-
- if(context->CurrentCullSign > 0)
- area = -area;
-
- if(area < context->MinTriArea)
- return;
-
- #undef x
- #undef y
- }
-
-
- fan.tex = context->w3dTexBuffer[context->CurrentBinding];
- fan.st_pattern = NULL;
- fan.v = verts;
- fan.vertexcount = pclip.numverts;
-
- error = W3D_DrawTriFanV(context->w3dContext, &fan);
- }
-
- void E_DrawFlatFan(GLcontext context, const int count, const UWORD *idx)
- {
- int i;
- int vnum;
- ULONG error;
- int Vstride;
- int Wstride;
- float *W;
- float *V;
- MGLVertex *v;
-
- Vstride = context->ArrayPointer.vertexstride;
- Wstride = context->ArrayPointer.texcoordstride;
-
- i = 0;
- do
- {
- vnum = idx[i];
-
- v = &context->VertexBuffer[vnum];
- V = (float*)(context->ArrayPointer.verts + vnum * Vstride);
-
- v->v.x = V[0];
- v->v.y = V[1];
- v->v.z = (double)V[2];
-
- if(context->ClientState & GLCS_TEXTURE)
- {
- W = (float*)((UBYTE*)context->WBuffer + vnum * Wstride);
- *W = 1.0;
- }
-
- i++;
- } while (i < count);
-
- error = W3D_DrawElements(context->w3dContext, W3D_PRIMITIVE_TRIFAN, W3D_INDEX_UWORD, count, (void *)idx);
- }
-
- //Range guardband-check added 18-05-02 (surgeon)
-
- INLINE ULONG TestRangeGuardBand(GLcontext context, GLuint first, GLsizei count)
- {
- int i;
- ULONG border;
- MGLVertex *v;
-
- v = &context->VertexBuffer[first];
-
- i = 0;
- border = 0;
-
- while (i < count && border == 0)
- {
- if(v->outcode)
- {
- float gcw = v->bw * 2.0;
-
- if (-gcw > v->bx)
- border |= MGL_CLIP_LEFT;
- else if (v->bx > gcw)
- border |= MGL_CLIP_RIGHT;
- if (-gcw > v->by)
- border |= MGL_CLIP_BOTTOM;
- else if (v->by > gcw)
- border |= MGL_CLIP_TOP;
- }
-
- i++;
- v++;
- }
-
- return border;
- }
-
- //FIXME: avoid redundary projections to a greater extent based on some simple statistics (on/off screen verts).
-
- void GLLockArrays(GLcontext context, GLuint first, GLsizei count)
- {
- int check_outcodes;
- ULONG offscreen;
-
- //pre-transform and code all verts within range:
-
- context->ArrayPointer.transformed = GL_TRUE;
- context->ArrayPointer.lockfirst = first;
- context->ArrayPointer.locksize = count;
-
- offscreen = TransformRange(context, first, count);
-
- //extra test added 18-05-02:
- if(offscreen && !(offscreen & context->ClipFlags))
- {
- check_outcodes = 1;
-
- offscreen = TestRangeGuardBand(context, first, count);
- }
- else
- {
- check_outcodes = 0;
- }
-
- //project verts:
-
- if (offscreen)
- {
- Clip_Volume_Bypass = GL_FALSE;
-
- //handles fix2float if needed:
-
- ProjectRangeByOutcode(context, first, count);
-
-
- context->w3dContext->VPMode = W3D_VERTEX_F_F_D;
- context->w3dContext->VertexPointer = (void *)&(context->VertexBuffer[0].v.x);
- }
- else //all vertices on screen
- {
- Clip_Volume_Bypass = GL_TRUE + check_outcodes;
-
- ProjectRange(context, first, count);
-
- //we don't need to move w3d vertexpointer
- //because only the results of the projection
- //are used later on.
- //However, path needs to be seperated from standard
- //because of backface culling.
- }
- }
-
- void GLUnlockArrays(GLcontext context)
- {
- context->ArrayPointer.transformed = GL_FALSE;
- context->ArrayPointer.lockfirst = 0;
- context->ArrayPointer.locksize = 0;
-
- if(Clip_Volume_Bypass == GL_FALSE)
- {
- context->w3dContext->VPMode = W3D_VERTEX_F_F_F;
- context->w3dContext->VertexPointer = (void *)&(context->VertexBuffer[0].bx);
- }
-
- Clip_Volume_Bypass = GL_FALSE;
- }
-
- static INLINE void PreDraw(GLcontext context)
- {
- if (context->FogDirty && context->Fog_State)
- {
- fog_Set(context);
- context->FogDirty = GL_FALSE;
- }
-
- if (context->ShadeModel == GL_FLAT && context->UpdateCurrentColor == GL_TRUE)
- {
- context->UpdateCurrentColor = GL_FALSE;
- W3D_SetCurrentColor(context->w3dContext, &context->CurrentColor);
- }
-
- #ifdef AUTOMATIC_LOCKING_ENABLE
-
- if (context->LockMode == MGL_LOCK_MANUAL)
- return;
-
- else if (context->LockMode == MGL_LOCK_AUTOMATIC) // Automatic: Lock per primitive
- {
- if (W3D_SUCCESS == W3D_LockHardware(context->w3dContext))
- {
- context->w3dLocked = GL_TRUE;
- }
- else
- {
- printf("Error during LockHardware\n");
- }
- }
- else // Smart: Lock timer based
- {
- if (context->w3dLocked == GL_FALSE)
- {
- if (W3D_SUCCESS != W3D_LockHardware(context->w3dContext))
- {
- return; // give up
- }
- context->w3dLocked = GL_TRUE;
- TMA_Start(&(context->LockTime));
- }
- }
-
- #endif
-
- }
-
- static INLINE void PostDraw(GLcontext context)
- {
- context->VertexBufferPointer = 0;
-
- #ifdef AUTOMATIC_LOCKING_ENABLE
-
- if (context->LockMode == MGL_LOCK_SMART && TMA_Check(&(context->LockTime)) == GL_TRUE)
- {
- // Time to unlock
- W3D_UnLockHardware(context->w3dContext);
- context->w3dLocked = GL_FALSE;
- }
- else if (context->LockMode == MGL_LOCK_AUTOMATIC)
- {
- W3D_UnLockHardware(context->w3dContext);
- context->w3dLocked = GL_FALSE;
- }
-
- #endif
-
- }
-
-
- void GLDrawElements(GLcontext context, GLenum mode, const GLsizei count, GLenum type, const GLvoid *indices)
- {
- int i;
- ULONG error, prim;
- UBYTE *ub;
- ULONG *ul;
- UWORD *idx;
-
- #ifdef VA_SANITY_CHECK
- GLboolean ShadeModel_bypass;
- GLboolean TexCoord_bypass;
- #endif
-
- switch(type)
- {
- case GL_UNSIGNED_SHORT:
- idx = (UWORD*)indices;
-
- break;
-
- case GL_UNSIGNED_BYTE:
-
- ub = (UBYTE *)indices;
- idx = context->ElementIndex;
-
- idx[0] = ub[0];
- idx[1] = ub[1];
- idx[2] = ub[2];
-
- i = 3;
-
- while (i < count)
- {
- idx[i] = ub[i];
- i++;
- }
- break;
-
- case GL_UNSIGNED_INT:
-
- ul = (ULONG *)indices;
- idx = context->ElementIndex;
-
- idx[0] = ul[0];
- idx[1] = ul[1];
- idx[2] = ul[2];
-
- i = 3;
-
- while (i < count)
- {
- idx[i] = ul[i];
- i++;
- }
-
- break;
-
- default:
-
- GLFlagError(context, 1, GL_INVALID_ENUM);
-
- break;
- }
-
- #ifdef VA_SANITY_CHECK
-
- ShadeModel_bypass = GL_FALSE;
-
- if(context->ShadeModel == GL_SMOOTH && !(context->ClientState & GLCS_COLOR))
- {
- W3D_SetState(context->w3dContext, W3D_GOURAUD, W3D_DISABLE);
- context->ShadeModel = GL_FLAT;
- ShadeModel_bypass = GL_TRUE;
- }
-
- #endif
-
- PreDraw(context);
-
- #ifdef VA_SANITY_CHECK
-
- TexCoord_bypass = GL_FALSE;
-
- if(context->Texture2D_State[0] == GL_FALSE || !(context->ClientState & GLCS_TEXTURE))
- {
- Set_W3D_Texture(context->w3dContext, 0, NULL);
-
- if(context->ClientState & GLCS_TEXTURE)
- {
- context->ClientState &= ~GLCS_TEXTURE;
- TexCoord_bypass = GL_TRUE;
- }
- }
-
- #else
-
- if(context->Texture2D_State[0] == GL_FALSE)
- {
- Set_W3D_Texture(context->w3dContext, 0, NULL);
- }
-
- #endif
-
- else
- {
- Set_W3D_Texture(context->w3dContext, 0, context->w3dTexBuffer[context->CurrentBinding]);
- }
-
-
- if(context->VertexArrayPipeline == GL_FALSE)
- {
- switch(mode)
- {
- case GL_POINTS:
- prim = W3D_PRIMITIVE_POINTS;
- break;
- case GL_LINE_STRIP:
- prim = W3D_PRIMITIVE_LINESTRIP;
- break;
- case GL_LINE_LOOP:
- prim = W3D_PRIMITIVE_LINELOOP;
- break;
- case GL_LINES:
- prim = W3D_PRIMITIVE_LINES;
- break;
- case GL_TRIANGLE_STRIP:
- prim = W3D_PRIMITIVE_TRISTRIP;
- break;
- case MGL_FLATFAN:
- case GL_POLYGON:
- case GL_TRIANGLE_FAN:
- prim = W3D_PRIMITIVE_TRIFAN;
- break;
- case GL_TRIANGLES:
- prim = W3D_PRIMITIVE_TRIANGLES;
- break;
- default:
- GLFlagError(context, 1, GL_INVALID_ENUM);
- }
-
- error = W3D_DrawElements(context->w3dContext, prim, W3D_INDEX_UWORD, count, (void*)&idx[0]);
- }
- else
- {
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- context->w3dContext->VPMode = W3D_VERTEX_F_F_D;
- context->w3dContext->VertexPointer = (void *)&(context->VertexBuffer[0].v.x);
-
- context->VertexBufferPointer = context->VertexBufferSize / 2;
- //avoid index-scan. Is this margin a safe assumption ?
- }
- else
- {
- context->VertexBufferPointer = context->ArrayPointer.lockfirst + context->ArrayPointer.locksize;
- }
-
- #if 0
- if((count == 3) && (mode != MGL_FLATFAN))
- {
- E_DrawTriangle(context, idx);
- }
- else
- #endif
- switch(mode)
- {
- case GL_TRIANGLE_STRIP:
- E_DrawTriStrip(context, count, idx);
- break;
-
- case GL_TRIANGLE_FAN:
- E_DrawTriFan(context, count, idx);
- break;
-
- case GL_TRIANGLES:
- E_DrawTriangles(context, count, idx);
- break;
-
- case GL_POLYGON:
- E_DrawPolygon(context, count, idx);
- break;
-
- case MGL_FLATFAN:
- E_DrawFlatFan(context, count, idx);
- break;
-
- default:
- GLFlagError(context, 1, GL_INVALID_ENUM);
- }
-
- if(context->ArrayPointer.transformed == GL_FALSE)
- {
- context->w3dContext->VPMode = W3D_VERTEX_F_F_F;
- context->w3dContext->VertexPointer = (void *)&(context->VertexBuffer[0].bx);
- }
- }
-
- PostDraw(context);
-
- #ifdef VA_SANITY_CHECK
-
- if(ShadeModel_bypass == GL_TRUE)
- {
- W3D_SetState(context->w3dContext, W3D_GOURAUD, W3D_ENABLE);
- context->ShadeModel = GL_SMOOTH;
- }
-
- if(TexCoord_bypass == GL_TRUE)
- {
- context->ClientState |= GLCS_TEXTURE;
- }
-
- #endif
-
- }
-
- #ifdef __VBCC__
- #undef V_ToScreen
- #endif
-